import { CoreService } from './../../services/core.service';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { PageTitleService, PageHeaderOption } from '../../services/page-title.service';
import { UserService } from 'src/app/services/user.service';
import { Menu } from 'src/app/models/menu';
import { NavMenu, NavMenuGroup } from 'src/app/models/nav-menu';
import { NavigationEnd, NavigationExtras, Router } from '@angular/router';
import { AuthorityService } from '../../common/authority/authority.service';
import { Account, Authority, User } from 'src/app/models';
import { Subscription } from 'rxjs';
import { version } from '../../../assets/version.json';
import { IMessageQueryParams, MessageService } from 'src/app/services/message.service';
import { Message } from 'src/app/models/message';
import { debounceTime, filter } from 'rxjs/operators';

@Component({
  selector: 'zepride-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.less']
})
export class HomeComponent implements OnInit, OnDestroy {

  isCollapsed: any;
  pageHeaderOptions: PageHeaderOption;
  orgInfo: any;
  loginUser: User;
  menus: (NavMenu | NavMenuGroup)[] = [];
  templates = [];
  router$: Subscription;
  version: string;
  messageList: Message[] = [];
  menuList: Menu[] = [];
  popoverVisible: boolean;
  newMessageSub: Subscription;

  constructor(
    private coreSvr: CoreService,
    private phSvr: PageTitleService,
    private userSvr: UserService,
    private router: Router,
    private authService: AuthorityService,
    public messageSvr: MessageService,
    private authorityService: AuthorityService
  ) {
    this.phSvr.OnPageTitleChange = this.onPageTitleChange.bind(this);
    this.version = version;
  }

  async ngOnInit() {
    this.setSuperPermits();
    this.loginUser = this.userSvr.user;
    const auths = await this.getUserAuthorities();
    this.authService.authorities = auths;
    this.getOrgInfo();
    await this.getOrgMenu(auths);
    this.initSelectFirstMenu();
    this.workflowPageCollapseMenu();
    this.queryMessage();
    this.newMessageSub = this.messageSvr.newMessage$.subscribe(msg => {
      this.queryMessage();
    });
    this.routerChange();
  }

  async queryMessage() {
    const orgId = localStorage.getItem('orgid');
    const userInfo = JSON.parse(localStorage.getItem('userInfo'));
    const params: IMessageQueryParams = {
      orgId,
      receiverIds: [userInfo.id]
    };
    this.messageList = await this.messageSvr.queryMessages(params);
  }

  messageClick(item: Message) {
    if (item.objectType == 'Workflow') {
      const menu = this.menuList.find(x => x.workflowId == item.objectId);
      this.selectMenu(menu, item.dataRegisterId);
    }
    this.popoverVisible = false;
  }

  initSelectFirstMenu() {
    const url = this.router.url;
    if (url.indexOf('page/workflow-page') > -1 || url.indexOf('page/normal-page') > -1) {
      return;
    }
    const menus = this.menus;
    if (menus && menus.length) {
      const menu: any = menus[0];
      const target = menu.children ? menu.children[0] : menu;
      menu.isOpen = true;
      this.selectMenu(target);
    }
  }

  selectMenu(menu: Menu, dataRegisterId?: string) {
    (menu as any).selected = true;
    let params: NavigationExtras;
    if (dataRegisterId) {
      params = {
        queryParams: {
          dataRegisterId
        }
      };
    }
    const url = this.router.url;
    if (menu.workflowId) {
      if (url.indexOf(menu.workflowId) > -1) {
        return;
      }
      this.router.navigate(['home/page/workflow-page', menu.workflowId], params);
    } else if (menu.pageId) {
      if (url.indexOf(menu.pageId) > -1) {
        return;
      }
      this.router.navigate(['home/page/normal-page', menu.pageId], params);
    }
  }

  onPageTitleChange(op: PageHeaderOption) {
    this.pageHeaderOptions = op;
  }

  async getOrgInfo() {
    const org = await this.coreSvr.getOrgInfo(this.coreSvr.orgid);
    this.coreSvr.org = org;
    this.orgInfo = org;
  }

  async getOrgMenu(authorities: Authority[]) {
    const menuData: { list: Menu[]; total: number; } = await this.coreSvr.getMenu(this.coreSvr.orgid);
    // const data = menuData.list ? menuData.list.filter(item => {
    //   if (item.isHide || item.isDelete) {
    //     return false;
    //   }
    //   const menuAuths = authorities.filter(auth => auth.refObjectType === 'Menu');
    //   if (menuAuths && menuAuths.length) {
    //     const existMenuAuth = menuAuths.find(menuAuth => menuAuth.refObjectId === item.id);
    //     return !!existMenuAuth;
    //   } else {
    //     return false;
    //   }
    // }) : [];
    this.menuList = menuData.list;
    const data = [];
    for (const menu of menuData.list) {
      if (menu.isDelete || menu.isHide) {
        continue;
      }
      const isAuthorized = this.authService.checkAuthority({ refObjectType: 'Menu', refObjectId: menu.id, mode: 'query' });
      if (isAuthorized) {
        data.push(menu);
      }
    }
    this.renderMenu(data);
  }

  logOut() {
    localStorage.removeItem('token');
    this.router.navigate(['login']);
  }

  buttonGroupClick(item: any) {
    if (item.onClick) {
      return item.onClick();
    } else {
      return;
    }
  }

  generateMenu(menus: Menu[]) {
    if (!menus || !menus.length) {
      return [];
    }
    const parentMenus: NavMenuGroup[] = menus.filter(menu => !menu.parentId) as NavMenuGroup[];
    const childMenus: Menu[] = menus.filter(menu => menu.parentId);
    if (Array.isArray(childMenus) && childMenus.length) {
      childMenus.forEach(child => {
        const parent = parentMenus.find(item => item.id === child.parentId);
        if (parent) {
          (parent as any).children = parent.children ? [...parent.children, child] : [child];
        }
      });
    }
    return parentMenus;
  }

  renderMenu(menus: Menu[]) {
    const hash = {};
    // 去重
    this.menus = this.generateMenu(menus).reduce((item, next) => {
      // tslint:disable-next-line: no-unused-expression
      hash[next.id] ? '' : hash[next.id] = true && item.push(next);
      return item;
    }, []);
  }

  getUserAuthorities(): Promise<Authority[]> {
    if (!this.loginUser || !this.loginUser.id || !this.loginUser.accountId) {
      // this.authService.authorities = [];
      return Promise.resolve([]);
    } else {
      return this.authService.getUserAuthorities({
        userId: this.loginUser.id,
        accountId: this.loginUser.accountId
      });
    }
  }

  workflowPageCollapseMenu() {
    this.router$ = this.router.events.subscribe((event) => {
      if (event instanceof NavigationEnd) {
        const url = event.url;
        if (url.indexOf('home/page/workflow-page') > -1) {
          this.isCollapsed = true;
        } else {
          this.isCollapsed = false;
        }
      }
    });
  }

  setSuperPermits() {
    const account: Account = this.userSvr.account;
    if (account.superPermits && account.superPermits.length) {
      const isSuperView = account.superPermits.find(permit => permit.permitId === '所有数据查看');
      const isSuperEdit = account.superPermits.find(permit => permit.permitId === '历史数据修改');
      this.authorityService.isSuperView = !!isSuperView;
      this.authorityService.isSuperEdit = !!isSuperEdit;
    } else {
      this.authorityService.isSuperView = false;
      this.authorityService.isSuperEdit = false;
    }
  }

  routerChange() {
    this.setMenuStatusByUrl(this.router.url);
    this.router.events.pipe(
      filter(evt => evt instanceof NavigationEnd),
      debounceTime(200)
    ).subscribe((event: NavigationEnd) => {
      const url = event.url;
      this.setMenuStatusByUrl(url);
    });
  }

  setMenuStatusByUrl(url: string) {
    if (url) {
      const urlParams = url.split('/');
      const pageType = urlParams[3];
      switch (pageType) {
        case 'normal-page':
          const pageId = urlParams[4];
          this.selectMenuById(pageId);
          break;
        case 'workflow-page':
          const workflowId = urlParams[4];
          this.selectMenuById(workflowId, 'workflow');
          break;
      }
    }
  }

  selectMenuById(itemId: string, type: 'normal' | 'workflow' = 'normal') {
    if (!itemId) {
      return;
    }
    if (itemId && itemId.indexOf('?') > -1) {
      itemId = itemId.split('?')[0];
    }
    for (const menu of this.menus) {
      if ((menu as NavMenuGroup).children && (menu as NavMenuGroup).children.length) {
        (menu as NavMenuGroup).children.forEach(item => {
          toggleMenuSelected(item, itemId, type);
        });
      } else {
        toggleMenuSelected(menu, itemId, type);
      }
    }

    function toggleMenuSelected(menuItem: NavMenu, targetId: string, pageType: 'normal' | 'workflow' = 'normal') {
      if (pageType === 'normal') {
        if (menuItem.pageId === targetId) {
          menuItem.selected = true;
        } else {
          delete menuItem.selected;
        }
      } else {
        if (menuItem.workflowId === targetId) {
          menuItem.selected = true;
        } else {
          delete menuItem.selected;
        }
      }
    }
  }

  ngOnDestroy() {
    if (this.router$) {
      this.router$.unsubscribe();
    }

    if (this.newMessageSub) {
      this.newMessageSub.unsubscribe();
    }
  }
}
